﻿using System.Collections.ObjectModel;
using InseSoft.Models.Entities;
using InseSoft.ViewModels;
using InseSoft.ViewModels.Events;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Ninject;

namespace InseSoft.Tests.Unit.ViewModels
{
    [TestClass]
    public class CatalogSearchViewModelTest
    {
        private readonly IEventPublisher eventPublisher;
        private readonly IKernel kernel;

        public CatalogSearchViewModelTest()
        {
            kernel = TestHelper.SetupDIKernel(); 
            eventPublisher = kernel.Get<IEventPublisher>();
        }

        [TestMethod]
        public void SearchPattern_NoMatches_EmptyRecordList()
        {
            var instance = kernel.Get<ICatalogSearchViewModel>();
            instance.RecordList = CreateTestList();
            instance.SearchPattern = "ZZZ";

            Assert.AreEqual(0, instance.FilteredList.Count);
        }

        [TestMethod]
        public void SearchPattern_Matches_RecordListFiltered()
        {
            var instance = kernel.Get<ICatalogSearchViewModel>();
            instance.RecordList = CreateTestList();

            instance.SearchPattern = "r";

            Assert.AreEqual(2, instance.FilteredList.Count);
            Assert.AreEqual("Cartago", instance.FilteredList[0].Nombre);
            Assert.AreEqual("Heredia", instance.FilteredList[1].Nombre);
        }
        
        [TestMethod]
        public void SelectedItem_ItemAssigned_CurrentEntityPopulated()
        {
            var recordList = CreateTestList();
            var instance = kernel.Get<ICatalogSearchViewModel>();
            instance.RecordList = recordList;
            instance.SelectedItem = recordList[2];

            Assert.AreEqual(recordList[2], instance.SelectedItem);
        }

        [TestMethod]
        public void SelectedItem_NoItemAssigned_DefaultCurrentEntityId()
        {
            var instance = kernel.Get<ICatalogSearchViewModel>();
            instance.RecordList = CreateTestList();

            Assert.IsNull(instance.SelectedItem);
        }

        [TestMethod]
        public void ItemAdded_EventTriggered_NewItemAddedToList()
        {
            var instance = kernel.Get<ICatalogSearchViewModel>();
            var newItem = new CatalogEntity {Id = 7, Nombre = "Puntarenas"};
            instance.RecordList = CreateTestList();
            var count = instance.RecordList.Count;

            eventPublisher.Publish(new EntityAdded(newItem));

            Assert.AreEqual(count+1, instance.RecordList.Count);
            Assert.AreEqual(instance.SelectedItem, newItem);
        }

        [TestMethod]
        public void ItemRemoved_EventTriggered_ItemRemovedFromList()
        {
            var instance = kernel.Get<ICatalogSearchViewModel>();
            instance.RecordList = CreateTestList();
            var itemToRemove = instance.RecordList[0];
            var count = instance.RecordList.Count;

            eventPublisher.Publish(new EntityRemoved(itemToRemove));

            Assert.AreEqual(count - 1, instance.RecordList.Count);
            Assert.AreEqual(string.Empty, instance.SearchPattern);
            Assert.AreEqual(instance.RecordList.Count, instance.FilteredList.Count);
        }
        
        
        [TestMethod]
        public void IocContainerTest()
        {
            var iocContainer = TestHelper.SetupDIKernel();
            var viewModel = iocContainer.Get<ICatalogSearchViewModel>();
            Assert.IsTrue(viewModel is CatalogSearchViewModel);
        }

        [TestMethod]
        public void IocContainerTest_Inject()
        {
            var iocContainer = TestHelper.SetupDIKernel();
            var viewModel = new CatalogEntityViewModel<Empresa>();
            iocContainer.Inject(viewModel);

            viewModel.DbContext.Empresas.Add(new Empresa());

            viewModel.Initialize();
        }

        #region Helpers
        
        private ObservableCollection<CatalogEntity> CreateTestList()
        {
            return new ObservableCollection<CatalogEntity>
            {
                new CatalogEntity{Id=1, Nombre = "San José"},
                new CatalogEntity{Id=2, Nombre = "Alajuela"},
                new CatalogEntity{Id=3, Nombre = "Cartago"},
                new CatalogEntity{Id=4, Nombre = "Heredia"},
            };
        }
        
        #endregion
    }
}
